#ifndef PROXY_CLIENT_USER_USERLOGIN_H_
#define PROXY_CLIENT_USER_USERLOGIN_H_

#include "vzconn/base/basicdefines.h"
#include "vzconn/conn/tcpclient.h"
#include "database_server/database_server_defines.h"

namespace proxy{

  class UserLoginSession : public boost::noncopyable,
    public boost::enable_shared_from_this< UserLoginSession >{
  public:
    typedef boost::shared_ptr<UserLoginSession> Ptr;

    typedef boost::function < void(UserLoginSession::Ptr ping_client,
      const boost::system::error_code& err) > SignalLoginFailureCallback;

    typedef boost::function < void(UserLoginSession::Ptr ping_client) >
      SignalLoginSucceedCallback;

    typedef boost::function < void(UserLoginSession::Ptr ping_client,
      const char* data, int size) > SignalOnlineServerListCallback;

    UserLoginSession(boost::asio::io_service& io_service, int timeout);
    virtual ~UserLoginSession();

    void SetSignalPingError(SignalLoginFailureCallback callback){
      SignalLoginFailure = callback;
    }

    void SetPingSucceedCallback(SignalLoginSucceedCallback callback){
      SignalLoginSucceed = callback;
    }

    void Start(const std::string user_name,
      const std::string password,
      const std::string server_addr,
      unsigned short server_port);
    void Stop();
    void StartPingMessage();
    bool StartGetOnlineProxyServer(const char* user_name, int size,
      SignalOnlineServerListCallback callback);
  private:
    // With TcpClient
    void OnServerConnect(vzconn::TcpConnect::Ptr connect,
      const boost::system::error_code& err, const std::string user_name,
      const std::string password);

    // With Timeout Message
    void HandleTimeout(const boost::system::error_code& err);

    // With Tcp Connect
    void OnConnectError(vzconn::TcpConnect::Ptr connect,
      const boost::system::error_code& err);
    void OnConnectWrite(vzconn::TcpConnect::Ptr connect);
    void OnConnectRead(vzconn::TcpConnect::Ptr connect,
      const char* buffer, int size, int flag);

    // Login with the server
    void StartLogin(const std::string user_name, const std::string password);
  private:
    boost::asio::io_service& io_service_;
    vzconn::TcpConnect::Ptr connect_;

    int timeout_;
    int ping_times_;
    boost::scoped_ptr<boost::asio::deadline_timer> timer_;
    SignalLoginFailureCallback SignalLoginFailure;
    SignalLoginSucceedCallback SignalLoginSucceed;
    SignalOnlineServerListCallback SignalOnlineServerList;
  };
}

#endif // PROXY_CLIENT_USER_USERLOGIN_H_